#ifndef __MESH_H__
#define __MESH_H__

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

#include <dalelib/graphics/texture.h>
#include <dalelib/maths.h>
//#include "main.h"

namespace dalelib
{

class Mesh
{
public:

	struct Vertex
	{
		v3 _pos,_nrm,_col,_uv;
		Vertex() { }
		Vertex(const v3 _Pos,const v3 _Nrm=v3::zero,const v3 _Col=v3::one,const v3 _UV=v3::zero)
			: _pos(_Pos)
			, _nrm(_Nrm)
			, _col(_Col)
			, _uv(_UV)
		{ }
	};

	struct Triangle
	{
		int v[3];
		Triangle(int V0,int V1,int V2)
		{
			v[0]=V0;
			v[1]=V1;
			v[2]=V2;
		}
	};

protected:

	bool _loaded;

	vector<Vertex> _vertex_array;
	vector<Triangle> _triangle_array;
	vector<GLuint> _index_array;

public:

	Mesh() : _loaded(false) { }
	~Mesh() { }

	GLuint getNumVertices() { return _vertex_array.size(); }
	GLuint getNumIndices() { return _index_array.size(); }
	vector<Vertex>& getVertexArray() { return _vertex_array; }
	vector<Triangle>& getTriangleArray() { return _triangle_array; }
	vector<GLuint>& getIndexArray() { return _index_array; }

	void clear()
	{
		_vertex_array.clear();
		_triangle_array.clear();
		_index_array.clear();
	}
//	void loadTexture(const string _Name);
	int addVertex( const v3 _Pos, const v3 _Nrm=v3::zero, const v3 _Col=v3::one,const v3 _UV=v3::zero)
	{
		_vertex_array.push_back(Vertex(_Pos,_Nrm,_Col,_UV));
		return _vertex_array.size()-1;
	}
	int addTriangle( const int _P0, const int _P1, const int _P2)
	{
		Triangle t(_P0,_P1,_P2);
		v3 nrm = v3::cross(_vertex_array[_P1]._pos-_vertex_array[_P0]._pos,_vertex_array[_P2]._pos-_vertex_array[_P0]._pos);
		v3 avnrm = _vertex_array[_P0]._nrm + _vertex_array[_P1]._nrm + _vertex_array[_P2]._nrm;
		if(v3::dot(nrm,avnrm)<0.f) // flip face
		{
			t.v[0] = _P1;
			t.v[1] = _P0;
		}
		_triangle_array.push_back(t);
		return _triangle_array.size()-1;
	}
	void loadPLY(const string _Name);
	void createIndexArray();
	void calcNormals();
	void invertNormals();
	void transform(const m4 _Transform);
	void draw();
	void dump();

};

} // namespace dalelib

#endif
